package com.kr.weitao.util;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author iBo @Description: 时间相关工具
 * @date 2014-8-30 下午10:42:21
 */
public class TimeUtils {

    public static final SimpleDateFormat DATE_FORMAT_DATE = new SimpleDateFormat("yyyy-MM-dd");
    public static final SimpleDateFormat DATE_FORMAT_DATE_NO = new SimpleDateFormat("yyyyMMdd");
    public static final SimpleDateFormat DATETIME_FORMAT_DATE =
            new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    public static final SimpleDateFormat DATETIME_FORMAT_DATE_NO =
            new SimpleDateFormat("yyyyMMddHHmmss");
    //  public static final SimpleDateFormat DATETIME_FORMAT_DATE_no =
//      new SimpleDateFormat("yyyy-MM-dd HH:mm");
//  public static final SimpleDateFormat DATETIME_FORMAT_DATE_MS =
//      new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");


    public static final SimpleDateFormat MONTH_FORMAT = new SimpleDateFormat("yyyyMM");
    public static final SimpleDateFormat FORMAT_DATE = new SimpleDateFormat("MMdd");
    public static final SimpleDateFormat FORMAT_MONTH = new SimpleDateFormat("MM");
    public static final SimpleDateFormat FORMAT_YEAR = new SimpleDateFormat("yyyy");

    /**
     * 获取某月第一天
     *
     * @param time 日期时间
     * @return
     * @throws Exception
     */
    public static String monthFirstDay(String time) throws Exception {
        Calendar calendar = Calendar.getInstance();
        // 设置时间,当前时间不用设置
        calendar.setTime(TimeUtils.MONTH_FORMAT.parse(time));
        // 设置日期为本月最大日期
        //		calendar.set(Calendar.DATE, calendar.getActualMaximum(Calendar.DATE));
        calendar.set(Calendar.DATE, calendar.getActualMinimum(Calendar.DATE));
        // 打印
        return TimeUtils.DATE_FORMAT_DATE_NO.format(calendar.getTime());
    }

    /**
     * @param date
     * @param dateFormat
     * @return
     */
    public static String formatDateByPattern(Date date, String dateFormat) {
        SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
        String formatTimeStr = null;
        if (date != null) {
            formatTimeStr = sdf.format(date);
        }
        return formatTimeStr;
    }

    /**
     * 获取某月最后一天
     *
     * @param time
     * @return
     * @throws Exception
     */
    public static String monthLastDay(String time) throws Exception {
        Calendar calendar = Calendar.getInstance();
        // 设置时间,当前时间不用设置
        calendar.setTime(TimeUtils.MONTH_FORMAT.parse(time));
        // 设置日期为本月最大日期
        calendar.set(Calendar.DATE, calendar.getActualMaximum(Calendar.DATE));
        //		calendar.set(Calendar.DATE,calendar.getActualMinimum(Calendar.DATE));
        // 打印
        return TimeUtils.DATE_FORMAT_DATE_NO.format(calendar.getTime());
    }

    /**
     * 根据指定日期 需要减去的天数 获取前一天的新日期
     *
     * @param date 日期 2016-5-17
     * @return 2016-5-16
     */
    public static Date getLastDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        date = calendar.getTime();
        return date;
    }

    /**
     * 根据指定日期 需要减去的天数 获取后一天的新日期
     *
     * @param date 日期 2016-5-17
     * @return 2016-5-16
     */
    public static Date getNextDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, 1);
        date = calendar.getTime();
        return date;
    }

    /**
     * 根据指定日期 需要减去的月数 获取减去或添加月数后的新日期
     *
     * @param date 日期 2016-5-17
     * @param i    减去的月数 1
     * @return 2016-4-17
     */
    public static Date getLastDate(Date date, int i) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.MONTH, i);
        return cal.getTime();
    }

    /**
     * 根据指定日期 需要减去的天数 获取减去或添加天数后的新日期
     *
     * @param date 日期 2016-5-17
     * @param i    减去的天数 7
     * @return 2016-5-10
     */
    public static Date getLastDateByDay(Date date, int i) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.DAY_OF_MONTH, i);
        return cal.getTime();
    }

    /**
     * long time to string
     *
     * @param timeInMillis
     * @param dateFormat
     * @return
     */
    public static String getTime(long timeInMillis, SimpleDateFormat dateFormat) {
        return dateFormat.format(new Date(timeInMillis));
    }

    /**
     * long time to string, format is {@link #}
     *
     * @param timeInMillis
     * @return
     */
    public static String getTime(long timeInMillis) {
        return getTime(timeInMillis, DATETIME_FORMAT_DATE);
    }

    /**
     * get current time in milliseconds
     *
     * @return
     */
    public static long getCurrentTimeInLong() {
        return System.currentTimeMillis();
    }

    public static int getCurrentYear() {
        Calendar cal = Calendar.getInstance();
        int year = cal.get(Calendar.YEAR);
        return year;
    }

    public static int getCurrentMonth() {
        Calendar cal = Calendar.getInstance();
        int month = cal.get(Calendar.MONTH) + 1;
        return month;
    }

    public static int getCurrentDay() {
        Calendar cal = Calendar.getInstance();
        int day = cal.get(Calendar.DATE);
        return day;
    }

    /**
     * get current time in milliseconds, format is {@link #}
     *
     * @return
     */
    public static String getCurrentTimeInString() {
        return getTime(getCurrentTimeInLong());
    }

    /**
     * get current time in milliseconds
     *
     * @return
     */
    public static String getCurrentTimeInString(SimpleDateFormat dateFormat) {
        return getTime(getCurrentTimeInLong(), dateFormat);
    }

    /**
     * @param :@param firstStr
     * @param :@param secondStr @Title: compareDateTime @Description: 比较日期大小
     */
    public static boolean compareDateTime(
            String firstStr, String secondStr, SimpleDateFormat simpleDateFormat) {
        Date firstDate = null;
        Date secondDate = null;
        try {
            firstDate = simpleDateFormat.parse(firstStr);
            secondDate = simpleDateFormat.parse(secondStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        long firstLongTime = firstDate.getTime();
        long secondLongTime = secondDate.getTime();
        if (firstLongTime >= secondLongTime) {
            return false;
        } else {
            return true;
        }
    }

    /**
     * 几天前
     *
     * @param beforDay
     * @param simpleDateFormat
     * @return
     */
    public static String getTimeBeforDay(int beforDay, SimpleDateFormat simpleDateFormat) {
        Calendar c = Calendar.getInstance();
        int day = c.get(Calendar.DAY_OF_MONTH) - beforDay;
        c.set(Calendar.DAY_OF_MONTH, day);
        return simpleDateFormat.format(c.getTime());
    }

    /**
     * 某日的几天前
     *
     * @param beforDay
     * @param simpleDateFormat
     * @return
     */
    public static String getTimeBefore(int beforDay, String date, SimpleDateFormat simpleDateFormat)
            throws Exception {
        Date days = simpleDateFormat.parse(date);
        Calendar c = Calendar.getInstance();
        c.setTime(days);
        int day = c.get(Calendar.DAY_OF_MONTH) - beforDay;
        c.set(Calendar.DAY_OF_MONTH, day);
        return simpleDateFormat.format(c.getTime());
    }

    /**
     * 获取两个日期相差天数
     *
     * @param date1
     * @param date2
     * @return
     * @throws ParseException
     */
    public static int calculateDateInDay(
            String date1, String date2, SimpleDateFormat simpleDateFormat) throws ParseException {

        Date now = simpleDateFormat.parse(date1);
        Date date = simpleDateFormat.parse(date2);
        long l = now.getTime() - date.getTime();
        long day = l / (24 * 60 * 60 * 1000);
        return (int) day;
    }

    /**
     * 获取两个日期相差小时数
     *
     * @param date1
     * @param date2
     * @param simpleDateFormat
     * @return
     * @throws ParseException
     */
    public static int calculateDateInHour(
            String date1, String date2, SimpleDateFormat simpleDateFormat) throws ParseException {

        Date now = simpleDateFormat.parse(date1);
        Date date = simpleDateFormat.parse(date2);
        long l = now.getTime() - date.getTime();
        long day = l / (60 * 60 * 1000);
        return (int) day;
    }

    /**
     * 某日所属的周一到周日
     *
     * @param date (yyyy-MM-dd)
     * @return
     * @throws Exception
     */
    public static String getWeek(String date) throws Exception {
        Date time = TimeUtils.DATE_FORMAT_DATE.parse(date);
        Calendar cal = Calendar.getInstance();
        cal.setTime(time);
        //判断要计算的日期是否是周日，如果是则减一天计算周六的，否则会出问题，计算到下一周去了
        int dayWeek = cal.get(Calendar.DAY_OF_WEEK); //获得当前日期是一个星期的第几天
        if (1 == dayWeek) {
            cal.add(Calendar.DAY_OF_MONTH, -1);
        }
        cal.setFirstDayOfWeek(Calendar.MONDAY); //设置一个星期的第一天，按中国的习惯一个星期的第一天是星期一
        int day = cal.get(Calendar.DAY_OF_WEEK); //获得当前日期是一个星期的第几天
        cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - day); //根据日历的规则，给当前日期减去星期几与一个星期第一天的差值

        String monday = TimeUtils.DATE_FORMAT_DATE.format(cal.getTime());
        cal.add(Calendar.DATE, 1);
        String tuesday = TimeUtils.DATE_FORMAT_DATE.format(cal.getTime());
        cal.add(Calendar.DATE, 1);
        String wednesday = TimeUtils.DATE_FORMAT_DATE.format(cal.getTime());
        cal.add(Calendar.DATE, 1);
        String thursday = TimeUtils.DATE_FORMAT_DATE.format(cal.getTime());
        cal.add(Calendar.DATE, 1);
        String friday = TimeUtils.DATE_FORMAT_DATE.format(cal.getTime());
        cal.add(Calendar.DATE, 1);
        String saturday = TimeUtils.DATE_FORMAT_DATE.format(cal.getTime());
        cal.add(Calendar.DATE, 1);
        String sunday = TimeUtils.DATE_FORMAT_DATE.format(cal.getTime());

        return monday + "," + tuesday + "," + wednesday + "," + thursday + "," + friday + "," + saturday
                + "," + sunday;
    }

    /**
     * 指定日期属于星期几
     *
     * @return
     */
    public static int dayForWeek(String date) throws Exception {

        Date time = TimeUtils.DATE_FORMAT_DATE.parse(date);
        Calendar cal = Calendar.getInstance();
        cal.setTime(time);

        int dayForWeek = 0;
        if (cal.get(Calendar.DAY_OF_WEEK) == 1) {
            dayForWeek = 7;
        } else {
            dayForWeek = cal.get(Calendar.DAY_OF_WEEK) - 1;
        }

        return dayForWeek;
    }

    public static int dayForWeek_(String pTime) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        c.setFirstDayOfWeek(Calendar.MONDAY);
        try {
            c.setTime(format.parse(pTime));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        int dayForWeek = 0;
        if (c.get(Calendar.DAY_OF_WEEK) == 1) {
            dayForWeek = 7;
        } else {
            dayForWeek = c.get(Calendar.DAY_OF_WEEK) - 1;
        }
        return dayForWeek - 1;
    }

    public static Map getFirstday_Lastday_Month(Date date) {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, -1);
        Date theDate = calendar.getTime();

        //上个月第一天
        GregorianCalendar gcLast = (GregorianCalendar) Calendar.getInstance();
        gcLast.setTime(theDate);
        gcLast.set(Calendar.DAY_OF_MONTH, 1);
        String day_first = df.format(gcLast.getTime());
        StringBuffer str = new StringBuffer().append(day_first).append(" 00:00:00");
        day_first = str.toString();

        //上个月最后一天
        calendar.add(Calendar.MONTH, 2); //加一个月
        calendar.set(Calendar.DATE, 1); //设置为该月第一天
        calendar.add(Calendar.DATE, -1); //再减一天即为上个月最后一天
        String day_last = df.format(calendar.getTime());
        StringBuffer endStr = new StringBuffer().append(day_last);
        day_last = endStr.toString();

        Map map = new HashMap();
        map.put("first", day_first);
        map.put("last", day_last);
        return map;
    }

    //获取该日期所属月份的最后一天日期"2012-05-02"
    public static String getLastDateByDate(String getDate) {
        Map map = null;
        try {
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
            String str = getDate;
            Date date = df.parse(str);
            map = getFirstday_Lastday_Month(date);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }

        return map.get("last").toString();
    }

    private static Date getMonthStart(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int index = calendar.get(Calendar.DAY_OF_MONTH);
        calendar.add(Calendar.DATE, (1 - index));
        return calendar.getTime();
    }

    private static Date getMonthEnd(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, 1);
        int index = calendar.get(Calendar.DAY_OF_MONTH);
        calendar.add(Calendar.DATE, (-index));
        return calendar.getTime();
    }

    //获取该月下的所有日期
    public static List<String> getMonthAllDays(String getDate) {
        List<String> dateList = new ArrayList();
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            String str = getDate;
            Date d = sdf.parse(str);
            // 月初
            //System.out.println("月初" + sdf.format(getMonthStart(d)));
            // 月末
            //System.out.println("月末" + sdf.format(getMonthEnd(d)));

            Date date = getMonthStart(d);
            Date monthEnd = getMonthEnd(d);
            while (!date.after(monthEnd)) {
                dateList.add(sdf.format(date));
                date = getNextDay(date);
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        return dateList;
    }

    /**
     * Get the Dates between Start Date and End Date.
     *
     * @param p_start Start Date
     * @param p_end   End Date
     * @return Dates List
     */
    public static List<String> getDates(Calendar p_start, Calendar p_end) {
        List<String> result = new ArrayList<String>();
        Calendar temp = p_start;
        p_end.add(Calendar.DAY_OF_YEAR, 1);
        while (temp.before(p_end)) {
            result.add(DATE_FORMAT_DATE.format(temp.getTime()));
            temp.add(Calendar.DAY_OF_YEAR, 1);
        }

        return result;
    }

    /**
     * 获取两个日期内的日期
     *
     * @param startDate
     * @param endDate
     * @return
     */
    public static List<String> getDaysByTwoDate(String startDate, String endDate) {
        List<String> dates = new ArrayList();
        try {
            Calendar dayc1 = new GregorianCalendar();
            DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
            Date daystart = df.parse(startDate); //start_date是类似"2013-02-02"的字符串
            dayc1.setTime(daystart);
            Calendar dayc2 = new GregorianCalendar();
            Date dayend = df.parse(endDate); //start_date是类似"2013-02-02"的字符串
            dayc2.setTime(dayend);
            dayc2.add(Calendar.MONTH, 0);
            dates = getDates(dayc1, dayc2);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        return dates;
    }

    /**
     * 获取某日期在一年的第几周
     *
     * @param time
     * @return
     * @throws ParseException
     */
    public static int getYearWeek(String time) throws ParseException {
        Calendar ca = Calendar.getInstance();
        SimpleDateFormat dsf = new SimpleDateFormat("yyyyMMdd");
        Date date = dsf.parse(time);

        ca.setTime(date);

        String year = time.substring(0, 4);
        String startDate = year + "0101";
        Date date1 = dsf.parse(startDate);
        Calendar ca1 = Calendar.getInstance();
        ca1.setTime(date1);

        String NextstartDate = (Integer.parseInt(year) + 1) + "0101";
        Date date2 = dsf.parse(NextstartDate);
        Calendar ca2 = Calendar.getInstance();
        ca2.setTime(date2);

        int weekDay = ca1.get(Calendar.DAY_OF_WEEK);
        int nextWeekDay = ca2.get(Calendar.DAY_OF_WEEK);
        int days = ca.get(Calendar.DAY_OF_YEAR);
        int intervalDays = 7 - (weekDay - 2); //今年第一周有几天

        int okDay = weekDay - 1; //今年的1号是星期几

        int koDay = nextWeekDay - 1; //下一年的1号是星期几

        if (intervalDays == 8) {
            intervalDays = 1;
        }

        if (okDay == 0) {
            okDay = 7;
        }

        if (koDay == 0) {
            koDay = 7;
        }

        if (okDay > 4) {
            if (days - intervalDays <= 0) {
                return getYearWeek((Integer.parseInt(year) - 1) + "1231");
            } else {
                if (ca.get(Calendar.WEEK_OF_YEAR) == 1) {
                    if (koDay >= 4) {
                        return 1;
                    } else {
                        return (days - intervalDays - 1) / 7 + 1;
                    }
                } else {
                    return (days - intervalDays - 1) / 7 + 1;
                }
            }

        } else {
            if (days - intervalDays <= 0) {
                return 1;
            } else {
                if (ca.get(Calendar.WEEK_OF_YEAR) == 1) {
                    if (koDay >= 4) {
                        return (days - intervalDays - 1) / 7 + 2;
                    } else {
                        return 1;
                    }
                } else {
                    return (days - intervalDays - 1) / 7 + 2;
                }
            }
        }
    }

    public static String convertTime(String time) throws Exception {
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
        Calendar c = new GregorianCalendar();
        c.setFirstDayOfWeek(Calendar.MONDAY);
        c.setMinimalDaysInFirstWeek(7);
        c.setTime(format.parse(time));
        String a_time_Y = String.valueOf(c.get(Calendar.YEAR));
        String a_time_W;
        String a_time_M;

        if (TimeUtils.getYearWeek(time) >= 10) {
            a_time_W = String.valueOf(TimeUtils.getYearWeek(time));
        } else {
            a_time_W = "0" + String.valueOf(TimeUtils.getYearWeek(time));
        }
        if (c.get(Calendar.MONTH) >= 9) {
            a_time_M = String.valueOf(c.get(Calendar.MONTH) + 1);
        } else {
            a_time_M = "0" + String.valueOf(c.get(Calendar.MONTH) + 1);
        }
        String a_time_D = time.substring(6);
        return a_time_Y + "," + a_time_M + "," + a_time_W + "," + a_time_D;
    }

    /**
     * 判断当前时间是否在指定时间之内
     * 开始时间为空              false
     * 结束时间为空              >=开始时间 true
     * 开始时间结束时间不为空    >=开始时间 <= 结束时间 true
     */
    public static boolean timeRange(String start_time, String end_time) throws Exception {
        long time = System.currentTimeMillis();
        boolean is_ture = false;
        if (StringUtils.isNull(start_time)) {
            return is_ture;
        }
        if (StringUtils.isNull(end_time)) {
            is_ture = time >= TimeUtils.DATETIME_FORMAT_DATE.parse(start_time).getTime();
            return is_ture;
        }
        is_ture = time >= TimeUtils.DATETIME_FORMAT_DATE.parse(start_time).getTime() && time <= TimeUtils.DATETIME_FORMAT_DATE.parse(end_time).getTime();
        return is_ture;
    }

    // 判断 yyyyMMdd 是否为当天
    public static boolean isTheDay(String day) {
        day = day.substring(4);
        String time = TimeUtils.getCurrentTimeInString(TimeUtils.FORMAT_DATE);
        if (day.equals(time)) {
            return true;
        }
        return false;
    }

    // 判断 yyyyMMdd 是否为当月
    public static boolean isTheMonth(String day) {
        String time = TimeUtils.getCurrentTimeInString(TimeUtils.FORMAT_MONTH);
        day = day.substring(4, 6);
        if (day.equals(time)) {
            return true;
        }
        return false;
    }

    // 判断 当前年是否大于 day
    public static boolean BTheYear(String day) {
        String time = TimeUtils.getCurrentTimeInString(TimeUtils.FORMAT_YEAR);
        if (Integer.parseInt(time) > Integer.parseInt(day)) {
            return true;
        }
        return false;
    }

    public static void main(String[] args) throws Exception {

        //        System.out.println();
        ////        String time = TimeUtils.getCurrentTimeInString(TimeUtils.DATETIME_FORMAT_DATE_MS);
        ////
        ////        System.out.println(time);
        ////        System.out.println(TimeUtils.getLongTime(time, TimeUtils.DATETIME_FORMAT_DATE_MS));
        //
        //        System.out.println("lllllll:"+compareDateTime("2016-02-30","2016-04-31",TimeUtils.DATE_FORMAT_DATE));

    /*SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    String str = "2016-02-10";
    Date d = sdf.parse(str);
    // 月初
    System.out.println("月初" + sdf.format(getMonthStart(d)));
    // 月末
    System.out.println("月末" + sdf.format(getMonthEnd(d)));

    Date date = getMonthStart(d);
    Date monthEnd = getMonthEnd(d);
    while (!date.after(monthEnd)) {
        System.out.println(sdf.format(date));
        date = getNextDay(date);
    }*/

    /*System.out.println(TimeUtils.compareDateTime("2016-08-04","2016-08-04",TimeUtils.DATE_FORMAT_DATE));*/

    /* List<String> dates = getDaysByTwoDate("2013-02-22","2013-03-15");
    int i = 0;
    while (i < dates.size()){
        System.out.println(dates.get(i));
        i++;
    }*/
    /*String  name = "~!@#$%&*".equals("~!@#$%&*")?"1":"2";
            System.out.println(name);


            Calendar calendar = Calendar.getInstance();
            calendar.setTime(new Date());
            calendar.add(Calendar.DAY_OF_WEEK, 0);
            int index = calendar.get(Calendar.DAY_OF_WEEK);

            System.out.println(TimeUtils.getDateStr(calendar.getTime(),TimeUtils.DATE_FORMAT_DATE));
             String   timeStap = ""+System.currentTimeMillis();
            timeStap = timeStap.substring(0,10);
            System.out.print(timeStap);
            String  abc = null;
            if(!"".equals(abc) && null != abc){
                abc = "123";
            }

            System.out.println("abc:"+abc);
    */

        //        int i = "1999.01".compareTo("2000.00");
        //        System.out.println("==i==" + i);

    }
}
